<template>
  <div class="face-recognition-manager">
    <div class="header">
      <div class="header-content">
        <div class="header-left">
          <h2 class="title">
            <i class="fa-solid fa-user-check mr-2"></i>
            人脸识别管理
          </h2>
          <p class="subtitle">管理已注册的人脸数据，支持人脸识别和行人跟踪功能</p>
        </div>
        <div class="header-right">
          <div class="user-info">
            <div class="user-avatar">
              <i class="fa-solid fa-user"></i>
            </div>
            <div class="user-details">
              <span class="username">{{ sysUser.username || '用户' }}</span>
              <span class="user-role">人脸识别用户</span>
            </div>
            <button @click="logout" class="logout-btn" title="退出登录">
              <i class="fa-solid fa-sign-out-alt"></i>
            </button>
          </div>
        </div>
      </div>
    </div>

    <!-- 功能控制区域 -->
    <div class="control-panel">
      <div class="control-row">
        <div class="control-group">
          <label class="control-label">人脸识别状态</label>
          <div class="toggle-container">
            <button 
              @click="toggleFaceRecognition"
              :class="['toggle-btn', { 'active': isFaceRecognitionEnabled }]"
              :disabled="isLoading">
              <i :class="isFaceRecognitionEnabled ? 'fa-solid fa-eye' : 'fa-solid fa-eye-slash'"></i>
              {{ isFaceRecognitionEnabled ? '已启用' : '已禁用' }}
            </button>
          </div>
        </div>

        <div class="control-group">
          <label class="control-label">行人跟踪状态</label>
          <div class="toggle-container">
            <button 
              @click="togglePersonTracking"
              :class="['toggle-btn', { 'active': isPersonTrackingEnabled }]"
              :disabled="isLoading">
              <i :class="isPersonTrackingEnabled ? 'fa-solid fa-walking' : 'fa-solid fa-stop'"></i>
              {{ isPersonTrackingEnabled ? '已启用' : '已禁用' }}
            </button>
          </div>
        </div>

        <div class="control-group">
          <button @click="trainModel" class="action-btn primary" :disabled="isLoading">
            <i class="fa-solid fa-brain mr-1"></i>
            训练模型
          </button>
        </div>
      </div>
    </div>

    <!-- 添加新人员区域 -->
    <div class="add-person-section">
      <h3 class="section-title">
        <i class="fa-solid fa-user-plus mr-2"></i>
        添加新人员
      </h3>
      
      <div class="add-person-form">
        <div class="form-group">
          <label class="form-label">人员姓名</label>
          <input 
            v-model="newPersonName"
            type="text"
            class="form-input"
            placeholder="请输入人员姓名"
            :disabled="isLoading">
        </div>
        
        <div class="form-group">
          <label class="form-label">人脸照片</label>
          <div class="file-upload-area" @click="triggerFileUpload" @dragover.prevent @drop.prevent="handleFileDrop">
            <input 
              ref="fileInput"
              type="file"
              accept="image/*"
              @change="handleFileSelect"
              style="display: none">
            
            <div v-if="!selectedImage" class="upload-placeholder">
              <i class="fa-solid fa-cloud-upload-alt text-4xl text-gray-400 mb-2"></i>
              <p class="text-gray-500">点击选择照片或拖拽到此处</p>
              <p class="text-sm text-gray-400">支持 JPG、PNG 格式</p>
            </div>
            
            <div v-else class="image-preview">
              <img :src="selectedImage" alt="预览图片" class="preview-image">
              <button @click="removeImage" class="remove-image-btn">
                <i class="fa-solid fa-times"></i>
              </button>
            </div>
          </div>
        </div>
        
        <button 
          @click="addPerson"
          class="action-btn success"
          :disabled="!newPersonName || !selectedImage || isLoading">
          <i class="fa-solid fa-plus mr-1"></i>
          添加人员
        </button>
      </div>
    </div>

    <!-- 已注册人员列表 -->
    <div class="registered-persons-section">
      <h3 class="section-title">
        <i class="fa-solid fa-users mr-2"></i>
        已注册人员 ({{ registeredPersons.length }})
      </h3>
      
      <div v-if="isLoading" class="loading-state">
        <i class="fa-solid fa-spinner fa-spin text-2xl text-blue-500 mb-2"></i>
        <p class="text-gray-500">加载中...</p>
      </div>
      
      <div v-else-if="registeredPersons.length === 0" class="empty-state">
        <i class="fa-solid fa-user-slash text-4xl text-gray-300 mb-4"></i>
        <p class="text-gray-500">暂无已注册人员</p>
        <p class="text-sm text-gray-400">请添加人员的人脸数据</p>
      </div>
      
      <div v-else class="persons-grid">
        <div 
          v-for="person in registeredPersons" 
          :key="person"
          class="person-card">
          <div class="person-avatar">
            <i class="fa-solid fa-user text-2xl text-gray-400"></i>
          </div>
          <div class="person-info">
            <h4 class="person-name">{{ person }}</h4>
            <p class="person-status">已注册</p>
          </div>
          <div class="person-actions">
            <button 
              @click="deletePerson(person)"
              class="action-btn danger small"
              :disabled="isLoading">
              <i class="fa-solid fa-trash"></i>
            </button>
          </div>
        </div>
      </div>
    </div>

    <!-- 检测记录查询区域 -->
    <div class="detection-records-section">
      <h3 class="section-title">
        <i class="fa-solid fa-history mr-2"></i>
        检测记录查询
      </h3>
      
      <!-- 查询条件 -->
      <div class="search-form">
        <div class="form-row">
          <div class="form-group">
            <label class="form-label">选择用户</label>
            <select v-model="selectedUsername" class="form-select" @change="onUsernameChange">
              <option value="">全部用户</option>
              <option v-for="username in availableUsernames" :key="username" :value="username">
                {{ username }}
              </option>
            </select>
          </div>
          
          <div class="form-group">
            <label class="form-label">开始时间</label>
            <input 
              v-model="startTime" 
              type="datetime-local" 
              class="form-input"
              @change="searchRecords">
          </div>
          
          <div class="form-group">
            <label class="form-label">结束时间</label>
            <input 
              v-model="endTime" 
              type="datetime-local" 
              class="form-input"
              @change="searchRecords">
          </div>
          
          <div class="form-group">
            <button @click="searchRecords" class="action-btn primary" :disabled="isLoadingRecords">
              <i class="fa-solid fa-search mr-1"></i>
              查询
            </button>
          </div>
        </div>
      </div>
      
      <!-- 记录列表 -->
      <div class="records-container">
        <div v-if="isLoadingRecords" class="loading-state">
          <i class="fa-solid fa-spinner fa-spin text-2xl text-blue-500 mb-2"></i>
          <p class="text-gray-500">查询中...</p>
        </div>
        
        <div v-else-if="detectionRecords.length === 0" class="empty-state">
          <i class="fa-solid fa-search text-4xl text-gray-300 mb-4"></i>
          <p class="text-gray-500">暂无检测记录</p>
          <p class="text-sm text-gray-400">请调整查询条件或等待新的检测记录</p>
        </div>
        
        <div v-else class="records-list">
          <div class="records-header">
            <div class="record-item-header">
              <div class="col-user">用户</div>
              <div class="col-confidence">置信度</div>
              <div class="col-time">检测时间</div>
              <div class="col-position">位置</div>
              <div class="col-actions">操作</div>
            </div>
          </div>
          
          <div class="records-body">
            <div 
              v-for="record in detectionRecords" 
              :key="record.id"
              class="record-item">
              <div class="col-user">
                <div class="user-info">
                  <div class="user-avatar">
                    {{ record.username.charAt(0) }}
                  </div>
                  <span class="user-name">{{ record.username }}</span>
                </div>
              </div>
              
              <div class="col-confidence">
                <span class="confidence-badge" :class="getConfidenceClass(record.confidence)">
                  {{ Math.round(record.confidence) }}%
                </span>
              </div>
              
              <div class="col-time">
                <div class="time-info">
                  <div class="time-main">{{ formatDateTime(record.detectionTime) }}</div>
                  <div class="time-sub">{{ formatTimeAgo(record.detectionTime) }}</div>
                </div>
              </div>
              
              <div class="col-position">
                <div class="position-info">
                  <div class="position-coords">
                    ({{ record.faceX }}, {{ record.faceY }})
                  </div>
                  <div class="position-size">
                    {{ record.faceWidth }}×{{ record.faceHeight }}
                  </div>
                </div>
              </div>
              
              <div class="col-actions">
                <button 
                  @click="viewRecord(record)"
                  class="action-btn small"
                  title="查看详情">
                  <i class="fa-solid fa-eye"></i>
                </button>
                <button 
                  @click="playVideoAtTime(record)"
                  class="action-btn small primary"
                  title="回看录像">
                  <i class="fa-solid fa-play"></i>
                </button>
              </div>
            </div>
          </div>
        </div>
        
        <!-- 分页 -->
        <div v-if="totalPages > 1" class="pagination">
          <button 
            @click="goToPage(currentPage - 1)"
            :disabled="currentPage <= 0"
            class="page-btn">
            <i class="fa-solid fa-chevron-left"></i>
          </button>
          
          <span class="page-info">
            第 {{ currentPage + 1 }} 页，共 {{ totalPages }} 页
          </span>
          
          <button 
            @click="goToPage(currentPage + 1)"
            :disabled="currentPage >= totalPages - 1"
            class="page-btn">
            <i class="fa-solid fa-chevron-right"></i>
          </button>
        </div>
      </div>
    </div>

    <!-- 消息提示 -->
    <div v-if="message" :class="['message', messageType]">
      <i :class="messageIcon"></i>
      {{ message }}
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { getApiUrl, getConfig } from '../config/faceRecognitionConfig.js'
import { defineUser } from '../store/userStore.js'

// 路由和用户状态管理
const router = useRouter()
const sysUser = defineUser()

// 响应式数据
const isLoading = ref(false)
const isFaceRecognitionEnabled = ref(false)
const isPersonTrackingEnabled = ref(false)
const registeredPersons = ref([])
const newPersonName = ref('')
const selectedImage = ref(null)
const selectedFile = ref(null)
const message = ref('')
const messageType = ref('')
const messageIcon = ref('')

// 检测记录查询相关
const selectedUsername = ref('')
const startTime = ref('')
const endTime = ref('')
const availableUsernames = ref([])
const detectionRecords = ref([])
const isLoadingRecords = ref(false)
const currentPage = ref(0)
const totalPages = ref(0)
const totalElements = ref(0)

// 引用
const fileInput = ref(null)


// 生命周期
onMounted(() => {
  loadRegisteredPersons()
  loadServiceStatus()
  loadAvailableUsernames()
})

onUnmounted(() => {
  // 清理工作
})

// 方法
const loadRegisteredPersons = async () => {
  try {
    isLoading.value = true
    const response = await fetch(getApiUrl('getRegisteredFaces'))
    const result = await response.json()
    
    if (result.code === 200) {
      registeredPersons.value = result.data || []
    } else {
      showMessage('加载已注册人员失败: ' + result.message, 'error')
    }
  } catch (error) {
    console.error('加载已注册人员失败:', error)
    showMessage('加载已注册人员失败', 'error')
  } finally {
    isLoading.value = false
  }
}

const loadServiceStatus = async () => {
  try {
    const response = await fetch(getApiUrl('getStatus'))
    const result = await response.json()
    
    if (result.code === 200) {
      // 这里可以根据实际API返回的状态设置
      isFaceRecognitionEnabled.value = true
      isPersonTrackingEnabled.value = true
    }
  } catch (error) {
    console.error('加载服务状态失败:', error)
  }
}

const toggleFaceRecognition = () => {
  isFaceRecognitionEnabled.value = !isFaceRecognitionEnabled.value
  showMessage(`人脸识别已${isFaceRecognitionEnabled.value ? '启用' : '禁用'}`, 'info')
}

const togglePersonTracking = () => {
  isPersonTrackingEnabled.value = !isPersonTrackingEnabled.value
  showMessage(`行人跟踪已${isPersonTrackingEnabled.value ? '启用' : '禁用'}`, 'info')
}

const trainModel = async () => {
  try {
    isLoading.value = true
    const response = await fetch(getApiUrl('trainModel'), {
      method: 'POST'
    })
    const result = await response.json()
    
    if (result.code === 200) {
      showMessage('模型训练成功', 'success')
    } else {
      showMessage('模型训练失败: ' + result.message, 'error')
    }
  } catch (error) {
    console.error('训练模型失败:', error)
    showMessage('训练模型失败', 'error')
  } finally {
    isLoading.value = false
  }
}

const triggerFileUpload = () => {
  fileInput.value?.click()
}

const handleFileSelect = (event) => {
  const file = event.target.files[0]
  if (file) {
    processFile(file)
  }
}

const handleFileDrop = (event) => {
  const files = event.dataTransfer.files
  if (files.length > 0) {
    processFile(files[0])
  }
}

const processFile = (file) => {
  if (!file.type.startsWith('image/')) {
    showMessage('请选择图片文件', 'error')
    return
  }
  
  selectedFile.value = file
  
  const reader = new FileReader()
  reader.onload = (e) => {
    selectedImage.value = e.target.result
  }
  reader.readAsDataURL(file)
}

const removeImage = () => {
  selectedImage.value = null
  selectedFile.value = null
  if (fileInput.value) {
    fileInput.value.value = ''
  }
}

const addPerson = async () => {
  if (!newPersonName.value.trim() || !selectedFile.value) {
    showMessage('请填写人员姓名并选择照片', 'error')
    return
  }
  
  try {
    isLoading.value = true
    
    const formData = new FormData()
    formData.append('name', newPersonName.value.trim())
    formData.append('image', selectedFile.value)
    
    const response = await fetch(getApiUrl('addFaceSample'), {
      method: 'POST',
      body: formData
    })
    
    // 检查响应状态
    if (!response.ok) {
      if (response.status === 413) {
        showMessage('图片文件过大，请选择较小的图片', 'error')
        return
      }
      showMessage(`服务器错误: ${response.status} ${response.statusText}`, 'error')
      return
    }
    
    // 检查响应内容类型
    const contentType = response.headers.get('content-type')
    if (!contentType || !contentType.includes('application/json')) {
      const text = await response.text()
      console.error('服务器返回非JSON响应:', text)
      showMessage('服务器返回格式错误，请稍后重试', 'error')
      return
    }
    
    const result = await response.json()
    
    if (result.code === 200) {
      showMessage('人员添加成功', 'success')
      newPersonName.value = ''
      removeImage()
      loadRegisteredPersons()
    } else {
      showMessage('人员添加失败: ' + result.message, 'error')
    }
  } catch (error) {
    console.error('添加人员失败:', error)
    if (error instanceof SyntaxError && error.message.includes('JSON')) {
      showMessage('服务器返回格式错误，请稍后重试', 'error')
    } else {
      showMessage('添加人员失败: ' + error.message, 'error')
    }
  } finally {
    isLoading.value = false
  }
}

const deletePerson = async (name) => {
  if (!confirm(`确定要删除 ${name} 的人脸数据吗？`)) {
    return
  }
  
  try {
    isLoading.value = true
    
    const response = await fetch(`${getApiUrl('deleteFace')}/${encodeURIComponent(name)}`, {
      method: 'DELETE'
    })
    
    const result = await response.json()
    
    if (result.code === 200) {
      showMessage('人员删除成功', 'success')
      loadRegisteredPersons()
    } else {
      showMessage('人员删除失败: ' + result.message, 'error')
    }
  } catch (error) {
    console.error('删除人员失败:', error)
    showMessage('删除人员失败', 'error')
  } finally {
    isLoading.value = false
  }
}


// 检测记录查询方法
const loadAvailableUsernames = async () => {
  try {
    const response = await fetch('/api/face-detection-records/usernames')
    const result = await response.json()
    
    if (result.code === 200) {
      availableUsernames.value = result.data || []
    } else {
      console.error('加载用户名列表失败:', result.message)
    }
  } catch (error) {
    console.error('加载用户名列表失败:', error)
  }
}

const searchRecords = async () => {
  try {
    isLoadingRecords.value = true
    
    let url = `/api/face-detection-records/search?offset=${currentPage.value * 10}&limit=10`
    
    if (selectedUsername.value) {
      url += `&username=${encodeURIComponent(selectedUsername.value)}`
    }
    
    if (startTime.value) {
      url += `&startTime=${encodeURIComponent(startTime.value)}`
    }
    
    if (endTime.value) {
      url += `&endTime=${encodeURIComponent(endTime.value)}`
    }
    
    const response = await fetch(url)
    const result = await response.json()
    
    if (result.code === 200) {
      detectionRecords.value = result.data.records || []
      totalPages.value = Math.ceil((result.data.total || 0) / 10)
      totalElements.value = result.data.total || 0
    } else {
      showMessage('查询检测记录失败: ' + result.message, 'error')
    }
  } catch (error) {
    console.error('查询检测记录失败:', error)
    showMessage('查询检测记录失败', 'error')
  } finally {
    isLoadingRecords.value = false
  }
}

const onUsernameChange = () => {
  currentPage.value = 0
  searchRecords()
}

const goToPage = (page) => {
  if (page >= 0 && page < totalPages.value) {
    currentPage.value = page
    searchRecords()
  }
}

const getConfidenceClass = (confidence) => {
  if (confidence >= 80) return 'confidence-high'
  if (confidence >= 60) return 'confidence-medium'
  return 'confidence-low'
}

const formatDateTime = (dateTime) => {
  const date = new Date(dateTime)
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
}

const formatTimeAgo = (dateTime) => {
  const now = new Date()
  const date = new Date(dateTime)
  const diffMs = now - date
  const diffMins = Math.floor(diffMs / 60000)
  const diffHours = Math.floor(diffMins / 60)
  const diffDays = Math.floor(diffHours / 24)
  
  if (diffMins < 1) return '刚刚'
  if (diffMins < 60) return `${diffMins}分钟前`
  if (diffHours < 24) return `${diffHours}小时前`
  return `${diffDays}天前`
}

const viewRecord = (record) => {
  // 查看记录详情
  const details = `
    用户: ${record.username}
    置信度: ${record.confidence}%
    检测时间: ${formatDateTime(record.detectionTime)}
    位置: (${record.faceX}, ${record.faceY})
    尺寸: ${record.faceWidth}×${record.faceHeight}
    视频源: ${record.videoSource || '未知'}
    会话ID: ${record.sessionId || '未知'}
  `
  
  // 创建模态框显示详情
  const modal = document.createElement('div')
  modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50'
  modal.innerHTML = `
    <div class="bg-white rounded-lg p-6 max-w-md w-full mx-4">
      <div class="flex justify-between items-center mb-4">
        <h3 class="text-lg font-semibold">检测记录详情</h3>
        <button onclick="this.closest('.fixed').remove()" class="text-gray-500 hover:text-gray-700">
          <i class="fa-solid fa-times"></i>
        </button>
      </div>
      <div class="space-y-2 text-sm">
        <div><strong>用户:</strong> ${record.username}</div>
        <div><strong>置信度:</strong> ${record.confidence}%</div>
        <div><strong>检测时间:</strong> ${formatDateTime(record.detectionTime)}</div>
        <div><strong>位置:</strong> (${record.faceX}, ${record.faceY})</div>
        <div><strong>尺寸:</strong> ${record.faceWidth}×${record.faceHeight}</div>
        <div><strong>视频源:</strong> ${record.videoSource || '未知'}</div>
        <div><strong>会话ID:</strong> ${record.sessionId || '未知'}</div>
      </div>
      <div class="mt-6 flex justify-end">
        <button onclick="this.closest('.fixed').remove()" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
          关闭
        </button>
      </div>
    </div>
  `
  document.body.appendChild(modal)
}

const playVideoAtTime = (record) => {
  // 回看录像功能
  const detectionTime = new Date(record.detectionTime)
  const timeString = detectionTime.toISOString().replace('T', ' ').substring(0, 19)
  
  // 创建模态框显示回放选项
  const modal = document.createElement('div')
  modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50'
  modal.innerHTML = `
    <div class="bg-white rounded-lg p-6 max-w-md w-full mx-4">
      <div class="flex justify-between items-center mb-4">
        <h3 class="text-lg font-semibold">录像回放</h3>
        <button onclick="this.closest('.fixed').remove()" class="text-gray-500 hover:text-gray-700">
          <i class="fa-solid fa-times"></i>
        </button>
      </div>
      <div class="space-y-4">
        <div class="text-sm">
          <div><strong>用户:</strong> ${record.username}</div>
          <div><strong>检测时间:</strong> ${formatDateTime(record.detectionTime)}</div>
          <div><strong>置信度:</strong> ${record.confidence}%</div>
        </div>
        <div class="text-sm text-gray-600">
          录像回放功能正在开发中...
        </div>
        <div class="bg-yellow-50 border border-yellow-200 rounded p-3 text-sm text-yellow-800">
          <i class="fa-solid fa-info-circle mr-2"></i>
          该功能需要视频录制系统支持，目前暂未实现。
        </div>
      </div>
      <div class="mt-6 flex justify-end space-x-2">
        <button onclick="this.closest('.fixed').remove()" class="px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600">
          取消
        </button>
        <button onclick="this.closest('.fixed').remove()" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
          确定
        </button>
      </div>
    </div>
  `
  document.body.appendChild(modal)
}

const logout = () => {
  sysUser.uid = ''
  sysUser.username = ''
  router.push('/login')
}

const showMessage = (text, type) => {
  message.value = text
  messageType.value = type
  
  const icons = {
    success: 'fa-solid fa-check-circle',
    error: 'fa-solid fa-exclamation-circle',
    info: 'fa-solid fa-info-circle',
    warning: 'fa-solid fa-exclamation-triangle'
  }
  
  messageIcon.value = icons[type] || icons.info
  
  setTimeout(() => {
    message.value = ''
  }, 3000)
}
</script>

<style scoped>
.face-recognition-manager {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

.header {
  margin-bottom: 30px;
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 20px;
}

.header-left {
  flex: 1;
  min-width: 300px;
}

.header-right {
  flex-shrink: 0;
}

.title {
  font-size: 2rem;
  font-weight: bold;
  color: #1f2937;
  margin-bottom: 8px;
}

.subtitle {
  color: #6b7280;
  font-size: 1.1rem;
}

.user-info {
  display: flex;
  align-items: center;
  gap: 12px;
  background: white;
  padding: 12px 16px;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  border: 1px solid #e5e7eb;
}

.user-avatar {
  width: 40px;
  height: 40px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-size: 16px;
}

.user-details {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.username {
  font-weight: 600;
  color: #1f2937;
  font-size: 14px;
}

.user-role {
  font-size: 12px;
  color: #6b7280;
}

.logout-btn {
  background: none;
  border: none;
  color: #6b7280;
  cursor: pointer;
  padding: 8px;
  border-radius: 6px;
  transition: all 0.2s;
  font-size: 16px;
}

.logout-btn:hover {
  background: #fee2e2;
  color: #dc2626;
}

.control-panel {
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  margin-bottom: 24px;
}

.control-row {
  display: flex;
  gap: 24px;
  align-items: end;
  flex-wrap: wrap;
}

.control-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.control-label {
  font-weight: 500;
  color: #374151;
  font-size: 0.9rem;
}

.toggle-container {
  display: flex;
  align-items: center;
}

.toggle-btn {
  padding: 8px 16px;
  border: 2px solid #e5e7eb;
  background: white;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s;
  font-size: 0.9rem;
  display: flex;
  align-items: center;
  gap: 6px;
}

.toggle-btn:hover:not(:disabled) {
  border-color: #3b82f6;
}

.toggle-btn.active {
  background: #3b82f6;
  color: white;
  border-color: #3b82f6;
}

.toggle-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.action-btn {
  padding: 10px 20px;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-weight: 500;
  transition: all 0.2s;
  display: flex;
  align-items: center;
  gap: 6px;
}

.action-btn.primary {
  background: #3b82f6;
  color: white;
}

.action-btn.primary:hover:not(:disabled) {
  background: #2563eb;
}

.action-btn.success {
  background: #10b981;
  color: white;
}

.action-btn.success:hover:not(:disabled) {
  background: #059669;
}

.action-btn.secondary {
  background: #6b7280;
  color: white;
}

.action-btn.secondary:hover:not(:disabled) {
  background: #4b5563;
}

.action-btn.danger {
  background: #ef4444;
  color: white;
}

.action-btn.danger:hover:not(:disabled) {
  background: #dc2626;
}

.action-btn.small {
  padding: 6px 12px;
  font-size: 0.8rem;
}

.action-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.add-person-section,
.registered-persons-section,
.detection-section {
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  margin-bottom: 24px;
}

.section-title {
  font-size: 1.25rem;
  font-weight: 600;
  color: #1f2937;
  margin-bottom: 20px;
  display: flex;
  align-items: center;
}

.add-person-form {
  display: grid;
  gap: 20px;
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.form-label {
  font-weight: 500;
  color: #374151;
}

.form-input {
  padding: 10px 12px;
  border: 2px solid #e5e7eb;
  border-radius: 8px;
  font-size: 1rem;
  transition: border-color 0.2s;
}

.form-input:focus {
  outline: none;
  border-color: #3b82f6;
}

.file-upload-area {
  border: 2px dashed #d1d5db;
  border-radius: 8px;
  padding: 40px 20px;
  text-align: center;
  cursor: pointer;
  transition: all 0.2s;
}

.file-upload-area:hover {
  border-color: #3b82f6;
  background: #f8fafc;
}

.upload-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.image-preview {
  position: relative;
  display: inline-block;
}

.preview-image {
  max-width: 200px;
  max-height: 200px;
  border-radius: 8px;
  object-fit: cover;
}

.remove-image-btn {
  position: absolute;
  top: -8px;
  right: -8px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #ef4444;
  color: white;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8rem;
}

.loading-state,
.empty-state {
  text-align: center;
  padding: 40px 20px;
  color: #6b7280;
}

.persons-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 16px;
}

.person-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  background: #f9fafb;
}

.person-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #e5e7eb;
  display: flex;
  align-items: center;
  justify-content: center;
}

.person-info {
  flex: 1;
}

.person-name {
  font-weight: 500;
  color: #1f2937;
  margin: 0 0 4px 0;
}

.person-status {
  font-size: 0.8rem;
  color: #6b7280;
  margin: 0;
}

.person-actions {
  display: flex;
  gap: 8px;
}

.detection-controls {
  display: flex;
  gap: 12px;
  margin-bottom: 20px;
}

.detection-info {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
}

.info-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px;
  background: #f3f4f6;
  border-radius: 6px;
}

.info-label {
  font-weight: 500;
  color: #374151;
}

.info-value {
  font-weight: 600;
}

.info-value.success {
  color: #10b981;
}

.message {
  position: fixed;
  top: 20px;
  right: 20px;
  padding: 12px 20px;
  border-radius: 8px;
  color: white;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 8px;
  z-index: 1000;
  animation: slideIn 0.3s ease-out;
}

.message.success {
  background: #10b981;
}

.message.error {
  background: #ef4444;
}

.message.info {
  background: #3b82f6;
}

.message.warning {
  background: #f59e0b;
}

@keyframes slideIn {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

@media (max-width: 768px) {
  .control-row {
    flex-direction: column;
    align-items: stretch;
  }
  
  .persons-grid {
    grid-template-columns: 1fr;
  }
  
  .detection-info {
    grid-template-columns: 1fr;
  }
}

/* 检测记录查询样式 */
.detection-records-section {
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  margin-bottom: 24px;
}

.search-form {
  margin-bottom: 24px;
}

.form-row {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr auto;
  gap: 16px;
  align-items: end;
}

.form-select {
  padding: 10px 12px;
  border: 2px solid #e5e7eb;
  border-radius: 8px;
  font-size: 1rem;
  transition: border-color 0.2s;
  background: white;
}

.form-select:focus {
  outline: none;
  border-color: #3b82f6;
}

.records-container {
  margin-top: 20px;
}

.records-list {
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  overflow: hidden;
}

.records-header {
  background: #f9fafb;
  border-bottom: 1px solid #e5e7eb;
}

.record-item-header {
  display: grid;
  grid-template-columns: 2fr 1fr 2fr 1fr 1fr;
  gap: 16px;
  padding: 12px 16px;
  font-weight: 600;
  color: #374151;
  font-size: 0.9rem;
}

.records-body {
  max-height: 600px;
  overflow-y: auto;
}

.record-item {
  display: grid;
  grid-template-columns: 2fr 1fr 2fr 1fr 1fr;
  gap: 16px;
  padding: 16px;
  border-bottom: 1px solid #f3f4f6;
  align-items: center;
  transition: background-color 0.2s;
}

.record-item:hover {
  background: #f9fafb;
}

.record-item:last-child {
  border-bottom: none;
}

.user-info {
  display: flex;
  align-items: center;
  gap: 12px;
}

.user-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 0.9rem;
}

.user-name {
  font-weight: 500;
  color: #1f2937;
}

.confidence-badge {
  padding: 4px 8px;
  border-radius: 12px;
  font-size: 0.8rem;
  font-weight: 600;
  text-align: center;
}

.confidence-high {
  background: #dcfce7;
  color: #166534;
}

.confidence-medium {
  background: #fef3c7;
  color: #92400e;
}

.confidence-low {
  background: #fee2e2;
  color: #991b1b;
}

.time-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.time-main {
  font-weight: 500;
  color: #1f2937;
  font-size: 0.9rem;
}

.time-sub {
  font-size: 0.8rem;
  color: #6b7280;
}

.position-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.position-coords {
  font-size: 0.9rem;
  color: #1f2937;
  font-family: monospace;
}

.position-size {
  font-size: 0.8rem;
  color: #6b7280;
  font-family: monospace;
}

.pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 16px;
  margin-top: 20px;
  padding: 16px;
}

.page-btn {
  padding: 8px 12px;
  border: 1px solid #d1d5db;
  background: white;
  color: #374151;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s;
  display: flex;
  align-items: center;
  gap: 4px;
}

.page-btn:hover:not(:disabled) {
  background: #f3f4f6;
  border-color: #9ca3af;
}

.page-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.page-info {
  font-size: 0.9rem;
  color: #6b7280;
  font-weight: 500;
}
</style>
